/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gui;

import java.util.ArrayList;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import stendcontrol.Configurator;
import stendcontrol.DataSensor;
import stendcontrol.Experiment;
import stendcontrol.ExperimentContainer;
import stendcontrol.ExperimentContainerListener;
import stendcontrol.Func;
import stendcontrol.Param;

/**
 *
 * @author minaev
 */
public class ExperimentTreeModel implements TreeModel, 
        ExperimentContainerListener {

    private ExperimentContainer exp_con;
    private ArrayList<TreeModelListener> listens = new ArrayList<TreeModelListener>();

    public ExperimentTreeModel(ExperimentContainer exp_con) {
        this.exp_con = exp_con;
    }

    @Override
    public Object getRoot() {
        return exp_con;
    }

    @Override
    public Object getChild(Object parent, int index) {
        if (parent.getClass() == ExperimentContainer.class) {
            return ((ExperimentContainer) parent).getExp(index);
        } else if (parent.getClass() == Experiment.class) {
            return ((Experiment) parent).getDataSensor(index);
        } else if (parent.getClass() == DataSensor.class) {
            DataSensor ds = (DataSensor) parent;
            if (index >= ds.getCountFuncs()) {
                return ds.getParam(index - ds.getCountFuncs());
            } else {
                return ds.getFunc(index);
            }
        } else {
            return null;
        }
    }

    @Override
    public int getChildCount(Object parent) {
        if (parent.getClass() == ExperimentContainer.class) {
            return ((ExperimentContainer) parent).getSize();
        } else if (parent.getClass() == Experiment.class) {
            return Configurator.COUNT_SENSOR;
        } else if (parent.getClass() == DataSensor.class) {
            DataSensor ds = (DataSensor) parent;
            return ds.getCountFuncs() + ds.getCountParams();
        } else {
            return 0;
        }
    }

    @Override
    public boolean isLeaf(Object node) {
        if (node.getClass() == Func.class || node.getClass() == Param.class) {
            return true;
        } else {
            return false;
        }
    }


    @Override
    public int getIndexOfChild(Object parent, Object child) {
        if (parent.getClass() == ExperimentContainer.class) {
            return ((ExperimentContainer) parent).getIndexOfChild(
                    (Experiment) child);
        } else if (parent.getClass() == Experiment.class) {
            return ((Experiment) parent).getIndexDataSensor((DataSensor)child);
        } else if (parent.getClass() == DataSensor.class) {
            DataSensor ds = (DataSensor) parent;
            if (child.getClass()==Func.class) {
                return ds.getIndexFunc((Func)child);
            } else {
                return ds.getCountFuncs()+ds.getIndexParam((Param)child);
            }
        } else {
            return -1;
        }
    }

    
    @Override
    public void valueForPathChanged(TreePath path, Object newValue) {
    }
    
    @Override
    public void addTreeModelListener(TreeModelListener l) {
        listens.add(l);
    }

    @Override
    public void removeTreeModelListener(TreeModelListener l) {
        listens.remove(l);
    }

    public void updatePath(Object[] path){
        TreeModelEvent tme = new TreeModelEvent(this, path);
        for(TreeModelListener tml:listens){
            tml.treeStructureChanged(tme);
        }
    }
    
    @Override
    public void changed() {
        Object[] path = new Object[1];
        path[0]=getRoot();
        updatePath(path);
    }
}
